파일 업로드 설정하기
✒️ 2025-05-28 12:56 내용 수정
사전 준비
- Annotation 기반 설정 파일#프로젝트 설정, 방명록 만들기대로 파일들 및 패키지를 준비한다.
- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload 에서 사용하려는 버전의 Maven 항목을 복사해서 pom.xml의 dependencies에 붙여넣는다. (1.3.1버전 사용)
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
- https://mvnrepository.com/artifact/commons-io/commons-io 에서 사용하려는 버전의 Maven 항목을 복사해서 pom.xml의 dependencies에 붙여넣는다. (2.4버전 사용)
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
코드 작성
- src/main/resources 폴더에 context 패키지에 Context_4_fileupload.java 파일을 생성하고, CommonsMultipartResolver 객체 Bean 생성한다.
- CommonsMultipartResolver 객체의 Encoding을 utf-8로 설정하고, 최대 업로드 용량을 지정한다.
package context;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@Configuration
public class Context_4_fileupload {
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setDefaultEncoding("utf-8");
// 최대 업로드 용량을 10mb로 지정
multipartResolver.setMaxUploadSize(10485760);
return multipartResolver;
}
}
- 새 Context.java를 추가했기에 src/main/resources 폴더의 config 패키지의 WebInitializer.java 파일에 해당 Context.class를 추가한다.
package config;
import javax.servlet.Filter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import context.Context_1_dataSource;
import context.Context_2_myBatis;
import context.Context_3_dao;
import context.Context_4_fileupload;
import mvc.ServletContext;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
// getRootConfigClasses
// 프로젝트의 모델 영역 설정 담당
// 데이터베이스 연결풀(DBCP), Mybatis, mapper 등과 같은 로직 설정 담당
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {Context_1_dataSource.class,
Context_2_myBatis.class,
Context_3_dao.class,
Context_4_fileupload.class};
}
// getServletConfigClasses
// DispatcherServlet이 사용할 설정 클래스를 반환
// Spring MVC 웹 영역 설정과 View, Controller 설정 담당
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {ServletContext.class};
}
// getServletMappings
// DispatcherServlet의 URL 패턴 지정
@Override
protected String[] getServletMappings() {
return new String[] {"/"}; // 모든 요청 처리
}
// filter
// 클라이언트 요청이 Servlet에 도달하기 전이나 후에
// 요청 및 응답 데이터 변형하거나 추가 작업 수행
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[] {characterEncodingFilter};
}
}
- src/main/java 폴더에 FileUploadController 클래스를 생성한다. 여기에서 파일 객체를 주입 받아 파일을 서버에 저장한다.
- 웹 프로젝트 경로에 resources/upload 폴더를 생성한다.
package com.nogruop.upload;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import dto.PhotoDTO;
import util.MyCommon;
@Controller
public class FileUploadController {
@Autowired // 자동 의존 주입
HttpServletRequest request;
@RequestMapping(value= {"/", "insert_form"})
public String insert_form() {
return MyCommon.VIEW_PATH+"insert_form.jsp";
}
@RequestMapping("upload")
public String upload(PhotoDTO dto) {
String webPath = "/resources/upload/"; // 웹 프로젝트 상의 경로
String savePath = request.getServletContext().getRealPath(webPath); // 실제 서버 경로
System.out.println(savePath);
// 업로드된 파일 정보
MultipartFile photo = dto.getPhoto();
String fileName = "no_file";
if(!photo.isEmpty()) {
fileName = photo.getOriginalFilename();
File saveFile = new File(savePath, fileName);
if(!saveFile.exists()) {
saveFile.mkdirs();
} else {
// 동일한 이름의 파일일 경우 폴더 형태로 변환 불가
// 업로드 시간을 붙여서 이름 중복을 방지
// System.currentTimeMillis()
long time = System.currentTimeMillis();
fileName = String.format("%d_%s", time, fileName);
saveFile = new File(savePath, fileName);
}
// 물리적으로 파일을 업로드
try {
photo.transferTo(saveFile);
} catch (Exception e) {
}
}
dto.setFilename(fileName);
request.setAttribute("dto", dto);
return MyCommon.VIEW_PATH+"insert_result.jsp";
}
}
- ServletContext에 자동 탐색으로 Component를 등록하도록 Annotation을 설정한다.
package mvc;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
@ComponentScan("com.nogroup.upload")
public class ServletContext implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
- 파일 업로드용 JSP 페이지를 생성하고 Mapping이 제대로 되는지 확인한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
function send(f) {
f.action = "upload";
f.submit();
}
</script>
</head>
<body>
<form method="post" enctype="multipart/form-data">
제목 : <input name="title"><br>
사진 : <input type="file" name="photo"><br>
<input type="button" value="전송" onclick="send(this.form)">
</form>
</body>
</html>
- src/main/resources 폴더에 dto 패키지를 만들고, PhotoDTO를 생성한다.
package dto;
import org.springframework.web.multipart.MultipartFile;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PhotoDTO {
private String title;
private String filename; // 진짜 파일 이름
private MultipartFile photo; // 넘어온 사진, 동영상 등 파일 형식
}
- 업로드한 이미지를 확인하기 위한 JSP 페이지를 만든다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
제목 : ${dto.title} <br>
<img src="resources/upload/${dto.filename}">
</body>
</html>